IOS Custom View 三部曲 Part 2 (Live Render)

Repo來源:CustomView

Live Render是IOS8之後才特有的功能,它提供了將你的Code可以在Storyboard上面即時的顯示,而不用再runtime的時候才能看見

  • Creating a Custom View that Renders in Interface Builder
    • By using the IBInspectable attribute to declare variables as inspectable properties, you allow Interface Builder to quickly rerender your custom view as you change the values of these properties in the Attributes inspector. You can attach the IBInspectable attribute to any property in a class declaration, class extension, or category for any type that’s supported by Interface Builder’s defined runtime attributes: boolean, integer or floating point number, string, localized string, rectangle, point, size, color, range, and nil.
    • If you need to create code for a custom view that runs only in Interface Builder, call that code from the method prepareForInterfaceBuilder. For example, while designing an app that uses the iPhone camera, you might want to draw an image that represents what the camera might capture. Although its compiled for runtime, code called from prepareForInterfaceBuilder never gets called except by Interface Builder at design time.
    • You can use the preprocessor macro TARGET_INTERFACE_BUILDER to specify code for inclusion with or exclusion from your custom view class.

簡而言之,Live Render能使用的資料型態就是User Defined Runtime Attributes所能提供的資料型態。

User Defined Runtime Attributes


Live Render Ver.Objetive-c (IOS 8)

Related Documents

Step 1 非常非常重要

  • 建立framework.
  • File -> New -> Target…
  • IOS -> Framework & Library -> Cocoa Touch Framework

Step 2

  • 建立一個繼承自UIView的CustomView類別

Step 3

  • 在你的類別中加入IB_DESIGNABLE
YourCustomVIew.h
1
2
3
4
#import <UIKit/UIKit.h>
IB_DESIGNABLE
@interface YourCustomView : UIView
@end

Step 4

  • 加入一些property,並且帶有IBInspectable
YourCustomVIiew.h
1
2
3
4
5
6
7
8
9
#import <UIKit/UIKit.h>
IB_DESIGNABLE
@interface YourCustomView : UIView
@property (nonatomic) IBInspectable NSInteger lineWidth;
@property (nonatomic) IBInspectable UIColor *fillColor;
@property (nonatomic) IBInspectable UIColor *labelColor;
@property (nonatomic) IBInspectable NSString *labelText;
@property (nonatomic) IBInspectable CGRect labelRect;
@end

Step 5 (分支 1)

  • 實作 drawRect方法
YourCustomView.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
- (void)drawRect:(CGRect)rect
{
UILabel *l =[[UILabel alloc] initWithFrame:_labelRect];
l.text = _labelText;
l.textColor = _labelColor;
[self addSubview:l];

// Drawing code
CGContextRef context = UIGraphicsGetCurrentContext();
CGRect myFrame = self.bounds;

// Set the line width to 10 and inset the rectangle by
// 5 pixels on all sides to compensate for the wider line.
CGContextSetLineWidth(context, _lineWidth);
CGRectInset(myFrame, 5, 5);

[_fillColor set];
UIRectFrame(myFrame);
}

Step 5 (分支 2)

  • 實作 initWithCoder & initWithFrame 方法
YourCustomView.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
@interface YourCustomView(){
dispatch_once_t onceTokenViewLiveRendering;
}
@property (nonatomic,strong) UILabel *label;
@end

@implementation YourCustomView

- (instancetype)initWithCoder:(NSCoder *)aDecoder{
self = [super initWithCoder:aDecoder];

if (self) {
[self setup];
}
return self;
}

- (instancetype)initWithFrame:(CGRect)frame{
self = [super initWithFrame:frame];

if (self) {
[self setup];
}
return self;
}

-(void)setup{
_label = [UILabel new];
[self addSubview:_label];
self.backgroundColor = [UIColor whiteColor];
}
@end

Step 6 (分支 2)

  • 實作 live render 方法(prepareForInterfaceBuilder & drawRect)

PS : some strange with live render方法.(我晚點會在這個地方解釋 Live Render Flow)

YourCustomView.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
-(void)prepareForInterfaceBuilder{
[self viewLiveRendering];
}

- (void)drawRect:(CGRect)rect{
#ifndef TARGET_INTERFACE_BUILDER
[self viewLiveRendering];
#endif
}

-(void)viewLiveRendering{
dispatch_once(&onceTokenViewLiveRendering, ^{
_label.frame = _labelRect;
_label.text = _labelText;
_label.textColor = _labelColor;
});
}

Live Render Ver.Swift (IOS 8)

Related Documents

Step 1 非常非常重要

  • 建立 framework.
  • File -> New -> Target…
  • IOS -> Framework & Library -> Cocoa Touch Framework

Step 2

  • 建立一個繼承自UIView的CustomView類別

Step 3

  • 在你的類別中加入@IB_DESIGNABLE
YourCustomView.swift
1
2
3
4
import UIKit
@IBDesignable
class YourCustomView: UIView {
}

Step 4

  • 加入一些instance variable,並且帶有@IBInspectable
  • 並且實作建構子,init(coder : NSCoder) & init(frame: CGRect)
YourCustomView.swift
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import UIKit
@IBDesignable
class YourCustomView: UIView {

@IBInspectable var labelColor: UIColor
@IBInspectable var labelText: NSString = ""
@IBInspectable var labelRect: CGRect

init(coder : NSCoder) {
labelColor = UIColor.blackColor()
//labelText = NSString()
labelRect = CGRect(x:0.0,y: 0.0,width: 200.0,height: 40.0)

super.init(coder:coder)
}
}

Step 5

  • 複寫 drawRect 方法
YourCustomView.swift
1
2
3
4
5
6
7
8
override func drawRect(rect: CGRect)
{
var l:UILabel = UILabel()
l.text = labelText
l.frame = labelRect
l.textColor = labelColor
addSubview(l)
}

Live Render Flow

APP running Debug Selected Views
(Live Rendering)
Function
path initWithCoder:




⬇︎
drawRect:
initWithFrame:

⬇︎
prepareForInterfaceBuilder

⬇︎
drawRect:
init method


Live Render 1


Draw